package com.yupi.yupicturebackend.api.baidu.imageUnderstand;

import cn.hutool.json.JSONObject;
import com.yupi.yupicturebackend.api.baidu.imageUnderstand.sub.ImageUnderstandingTaskCreator;
import com.yupi.yupicturebackend.api.baidu.imageUnderstand.sub.ImageUnderstandingTaskQuery;
import okhttp3.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Component
public class ImageUnderstandingFacade {
    private String apiKey;
    private String secretKey;
    private final OkHttpClient httpClient;
    private String accessToken;
    private long tokenExpireTime;

    private final ImageUnderstandingTaskCreator taskCreator;
    private final ImageUnderstandingTaskQuery taskQuery;

    // 使用构造器注入而不是final字段
    public ImageUnderstandingFacade(
            @Value("${baidu.apiKey}") String apiKey,
            @Value("${baidu.secretKey}") String secretKey) throws IOException {
        this.apiKey = apiKey;
        this.secretKey = secretKey;
        this.httpClient = new OkHttpClient.Builder()
                .connectTimeout(30, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
        this.accessToken = getAccessToken();
        this.taskCreator = new ImageUnderstandingTaskCreator(accessToken, httpClient);
        this.taskQuery = new ImageUnderstandingTaskQuery(accessToken, httpClient);
    }

    /**
     * 分析图片并返回描述（封装完整流程）
     */
    public String analyzeImageAndGetDescription(String imageUrl, String question) throws IOException {
        String taskId = createAnalysisTask(imageUrl, question);
        return getTaskDescription(taskId);
    }

    /**
     * 创建分析任务
     */
    public String createAnalysisTask(String imageUrl, String question) throws IOException {
        refreshTokenIfNeeded();
        return taskCreator.createTask(imageUrl, question);
    }

    /**
     * 获取任务描述（带轮询和超时）
     */
    public String getTaskDescription(String taskId) throws IOException {
        refreshTokenIfNeeded();

        // 轮询获取结果，最多尝试5次，每次间隔1秒
        int maxAttempts = 20;
        for (int i = 0; i < maxAttempts; i++) {
            JSONObject response = taskQuery.getTaskResult(taskId);

            // 1. 检查错误响应
            if (response.containsKey("error_code")) {
                throw new IOException("API error: " + response.getStr("error_msg"));
            }

            // 2. 获取result对象（根据实际API响应结构调整）
            JSONObject result = response.getJSONObject("result");
            if (result == null) {
                throw new IOException("Missing 'result' field in response");
            }

            // 3. 根据实际API状态字段判断（示例中是ret_code）
            if (result.getInt("ret_code") == 0) { // 成功状态码
                String description = result.getStr("description");
                if (description != null && !description.isEmpty()) {
                    return description;
                }
                throw new IOException("Empty description in response");
            }

            // 4. 等待1秒后重试
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                throw new IOException("Task interrupted", e);
            }
        }

        throw new IOException("Task processing timeout after " + maxAttempts + " attempts");
    }

    private synchronized void refreshTokenIfNeeded() throws IOException {
        if (accessToken == null || System.currentTimeMillis() > tokenExpireTime) {
            this.accessToken = getAccessToken();
            this.tokenExpireTime = System.currentTimeMillis() + 29 * 24 * 60 * 60 * 1000L;
            taskCreator.updateAccessToken(accessToken);
            taskQuery.updateAccessToken(accessToken);
        }
    }

    private String getAccessToken() throws IOException {
        MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
        RequestBody body = RequestBody.create(
                "grant_type=client_credentials&client_id=" + apiKey + "&client_secret=" + secretKey,
                mediaType);

        Request request = new Request.Builder()
                .url("https://aip.baidubce.com/oauth/2.0/token")
                .post(body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();

        try (Response response = httpClient.newCall(request).execute()) {
            JSONObject jsonResponse = new JSONObject(response.body().string());
            return jsonResponse.getStr("access_token");
        }
    }
}